﻿Imports System
Imports System.Data
Imports System.Configuration
Imports System.Collections
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Drawing
Imports System.IO

Partial Class Public_VerificationCode
    Inherits System.Web.UI.UserControl

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        If Not IsPostBack OrElse Session("CheckCode") Is Nothing Then
            Me.SetCode()
        End If
    End Sub

    '刷新驗證碼
    Protected Sub ibtnVerificationCode_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles ibtnVerificationCode.Click
        Me.SetCode()
    End Sub

    '驗證碼初始化
    Public Sub SetCode()
        Dim checkCode As String = Me.CreateRandomCode(4) '產生4個數字的驗證碼
        Me.Session("CheckCode") = checkCode
        Me.CreateImage(checkCode)
    End Sub

    '取得驗證碼
    Public Function CreateRandomCode(ByVal codeCount As Integer) As String
        'string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
        Dim allChar As String = "2,3,4,6,7,9,A,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,V,W,X,Y,Z" '去掉易混淆的字元
        Dim allCharArray() As String = allChar.Split(",")
        Dim randomCode As String = ""
        Dim temp As Integer = -1

        Dim rand As Random = New Random()
        Dim i As Integer
        For i = 0 To codeCount - 1
            If temp <> -1 Then
                rand = New Random(i * temp * DateTime.Now.Millisecond)
            End If
            Dim t As Integer = rand.Next(allCharArray.Length)
            If temp <> -1 And temp = t Then
                Return CreateRandomCode(codeCount)
            End If
            temp = t
            randomCode += allCharArray(t)
        Next
        Return randomCode
    End Function

    '產生驗證碼圖片
    Private Sub CreateImage(ByVal checkCode As String)
        Dim image As System.Drawing.Bitmap = New System.Drawing.Bitmap(Convert.ToInt32(Math.Ceiling(CType((checkCode.Length * 14), Decimal))), 22)
        Dim g As Graphics = Graphics.FromImage(image)

        Try
            Dim random As Random = New Random()
            g.Clear(Color.AliceBlue)

            Dim i As Integer
            For i = 0 To 25 - 1 Step i + 1
                Dim x1 As Integer = random.Next(image.Width)
                Dim x2 As Integer = random.Next(image.Width)
                Dim y1 As Integer = random.Next(image.Height)
                Dim y2 As Integer = random.Next(image.Height)

                g.DrawLine(New Pen(Color.Silver), x1, y1, x2, y2)
            Next

            Dim font As Font = New System.Drawing.Font("Comic Sans MS", 12, System.Drawing.FontStyle.Bold)
            Dim brush As System.Drawing.Drawing2D.LinearGradientBrush = New System.Drawing.Drawing2D.LinearGradientBrush(New Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2F, True)
            g.DrawString(checkCode, font, New SolidBrush(Color.Red), 2, 2)

            For i = 0 To 100 - 1 Step i + 1
                Dim x As Integer = random.Next(image.Width)
                Dim y As Integer = random.Next(image.Height)

                image.SetPixel(x, y, Color.FromArgb(random.Next()))
            Next
            g.DrawRectangle(New Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1)

            ibtnVerificationCode.ImageUrl = "data:image/" & GetImageFormat(image).ToString() & ";base64," + ImageToBase64(image)
        Finally
            g.Dispose()
            image.Dispose()
        End Try
    End Sub

    '/ <summary>
    '/ 自動判斷圖片格式
    '/ </summary>
    '/ <param name="img"></param>
    '/ <returns></returns>
    Public Shared Function GetImageFormat(ByVal img As System.Drawing.Image) As System.Drawing.Imaging.ImageFormat
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg) Then
            Return System.Drawing.Imaging.ImageFormat.Jpeg
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp) Then
            Return System.Drawing.Imaging.ImageFormat.Bmp
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png) Then
            Return System.Drawing.Imaging.ImageFormat.Png
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf) Then
            Return System.Drawing.Imaging.ImageFormat.Emf
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif) Then
            Return System.Drawing.Imaging.ImageFormat.Exif
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif) Then
            Return System.Drawing.Imaging.ImageFormat.Gif
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon) Then
            Return System.Drawing.Imaging.ImageFormat.Icon
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp) Then
            Return System.Drawing.Imaging.ImageFormat.MemoryBmp
        End If
        If img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff) Then
            Return System.Drawing.Imaging.ImageFormat.Tiff
        End If
        Return System.Drawing.Imaging.ImageFormat.Wmf
    End Function

    '/ <summary>
    '/ 將 Image 物件轉 Base64
    '/ Convert image to base64
    '/ </summary>
    '/ <param name="image"></param>
    '/ <returns></returns>
    Public Function ImageToBase64(ByVal image As Bitmap) As String
        Dim ms As MemoryStream = New MemoryStream()

        ' 將圖片轉成 byte[]
        ' Comvert image to byte[]
        image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
        Dim imageBytes() As Byte = ms.ToArray()

        ' 將 byte[] 轉 base64
        ' byte to base64
        Dim base64String As String = Convert.ToBase64String(imageBytes)
        Return base64String

    End Function

    '回傳目前驗證碼的值
    Public ReadOnly Property VerificationCode() As String
        Get
            Return Session("CheckCode")
        End Get
    End Property


End Class